





#include "mixer_soft.h"

#include "error_macros.h"

#include <stdio.h>

#define PI_VALUE  3.14159265358979323846

float dmpfac[] = {
	131072, 128272, 125533, 122852, 120229, 117661, 115148, 112689,
	110283, 107928, 105623, 103367, 101160,  98999,  96885,  94816,
	92791,  90810,  88870,  86973,  85115,  83298,  81519,  79778,
	78074,  76407,  74775,  73178,  71615,  70086,  68589,  67125,
	65691,  64288,  62915,  61572,  60257,  58970,  57711,  56478,
	55272,  54092,  52937,  51806,  50700,  49617,  48557,  47520,
	46506,  45512,  44540,  43589,  42658,  41747,  40856,  39983,
	39130,  38294,  37476,  36676,  35893,  35126,  34376,  33642,
	32923,  32220,  31532,  30859,  30200,  29555,  28924,  28306,
	27701,  27110,  26531,  25964,  25410,  24867,  24336,  23816,
	23308,  22810,  22323,  21846,  21380,  20923,  20476,  20039,
	19611,  19192,  18782,  18381,  17989,  17604,  17228,  16861,
	16500,  16148,  15803,  15466,  15135,  14812,  14496,  14186,
	13883,  13587,  13297,  13013,  12735,  12463,  12197,  11936,
	11681,  11432,  11188,  10949,  10715,  10486,  10262,  10043,
	9829,   9619,   9413,   9212,   9015,   8823,   8634,   8450,
	8270,   8093,   7920,   7751,   7585,   7423,   7265,   7110,
	6958,   6809,   6664,   6522,   6382,   6246,   6113,   5982,
	5854,   5729,   5607,   5487,   5370,   5255,   5143,   5033,
	4926,   4820,   4718,   4617,   4518,   4422,   4327,   4235,
	4144,   4056,   3969,   3884,   3801,   3720,   3641,   3563,
	3487,   3412,   3340,   3268,   3198,   3130,   3063,   2998,
	2934,   2871,   2810,   2750,   2691,   2634,   2577,   2522,
	2468,   2416,   2364,   2314,   2264,   2216,   2169,   2122,
	2077,   2032,   1989,   1947,   1905,   1864,   1824,   1786,
	1747,   1710,   1674,   1638,   1603,   1569,   1535,   1502,
	1470,   1439,   1408,   1378,   1348,   1320,   1291,   1264,
	1237,   1210,   1185,   1159,   1135,   1110,   1087,   1063,
	1041,   1018,    997,    975,    955,    934,    914,    895,
	876,    857,    838,    821,    803,    786,    769,    753,
	737,    721,    705,    690,    676,    661,    647,    633,
	620,    606,    593,    581,    568,    556,    544,    533
};

static const float losstable[128]={1.0,0.97864,0.95774,0.93729,0.91727,0.89768,0.87851,0.85975,
0.84139,0.82342,0.80584,0.78863,0.77179,0.75530,0.73917,0.72339,
0.70794,0.69282,0.67803,0.66355,0.64938,0.63551,0.62194,0.60866,
0.59566,0.58294,0.57049,0.55830,0.54638,0.53471,0.52329,0.51212,
0.50118,0.49048,0.48000,0.46975,0.45972,0.44990,0.44030,0.43089,
0.42169,0.41269,0.40387,0.39525,0.38681,0.37855,0.37046,0.36255,
0.35481,0.34723,0.33982,0.33256,0.32546,0.31851,0.31170,0.30505,
0.29853,0.29216,0.28592,0.27981,0.27384,0.26799,0.26227,0.25666,
0.25118,0.24582,0.24057,0.23543,0.23040,0.22548,0.22067,0.21596,
0.21134,0.20683,0.20241,0.19809,0.19386,0.18972,0.18567,0.18170,
0.17782,0.17403,0.17031,0.16667,0.16311,0.15963,0.15622,0.15288,
0.14962,0.14642,0.14330,0.14024,0.13724,0.13431,0.13144,0.12863,
0.12589,0.12320,0.12057,0.11799,0.11547,0.11301,0.11059,0.10823,
0.10592,0.10366,0.10144,0.09928,0.09716,0.09508,0.09305,0.09106,
0.08912,0.08722,0.08535,0.08353,0.08175,0.08000,0.07829,0.07662,
0.07498,0.07338,0.07182,0.07028,0.06878,0.06731,0.06587,0.06447};



static const float _it_cutoff_table[128]={
        0.0012166619999334,
        0.0011820259969682,
        0.0011483760317788,
        0.0011156840482727,
        0.0010839226888493,
        0.0010530654108152,
        0.0010230867192149,
        0.0009939613519236,
        0.0009656652691774,
        0.0009381746640429,
        0.0009114666027017,
        0.0008855189662427,
        0.0008603099850006,
        0.0008358185878024,
        0.0008120245183818,
        0.0007889076950960,
        0.0007664490840398,
        0.0007446297095157,
        0.0007234315853566,
        0.0007028369000182,
        0.0006828284822404,
        0.0006633896846324,
        0.0006445042672567,
        0.0006261564558372,
        0.0006083309999667,
        0.0005910129984841,
        0.0005741880158894,
        0.0005578420241363,
        0.0005419613444246,
        0.0005265327054076,
        0.0005115433596075,
        0.0004969806759618,
        0.0004828326345887,
        0.0004690873320214,
        0.0004557333013508,
        0.0004427594831213,
        0.0004301549925003,
        0.0004179092939012,
        0.0004060122591909,
        0.0003944538475480,
        0.0003832245420199,
        0.0003723148547579,
        0.0003617157926783,
        0.0003514184500091,
        0.0003414142411202,
        0.0003316948423162,
        0.0003222521336284,
        0.0003130782279186,
        0.0003041654999834,
        0.0002955064992420,
        0.0002870940079447,
        0.0002789210120682,
        0.0002709806722123,
        0.0002632663527038,
        0.0002557716798037,
        0.0002484903379809,
        0.0002414163172944,
        0.0002345436660107,
        0.0002278666506754,
        0.0002213797415607,
        0.0002150774962502,
        0.0002089546469506,
        0.0002030061295955,
        0.0001972269237740,
        0.0001916122710099,
        0.0001861574273789,
        0.0001808578963391,
        0.0001757092250045,
        0.0001707071205601,
        0.0001658474211581,
        0.0001611260668142,
        0.0001565391139593,
        0.0001520827499917,
        0.0001477532496210,
        0.0001435470039723,
        0.0001394605060341,
        0.0001354903361062,
        0.0001316331763519,
        0.0001278858399019,
        0.0001242451689905,
        0.0001207081586472,
        0.0001172718330054,
        0.0001139333253377,
        0.0001106898707803,
        0.0001075387481251,
        0.0001044773234753,
        0.0001015030647977,
        0.0000986134618870,
        0.0000958061355050,
        0.0000930787136895,
        0.0000904289481696,
        0.0000878546125023,
        0.0000853535602801,
        0.0000829237105791,
        0.0000805630334071,
        0.0000782695569796,
        0.0000760413749958,
        0.0000738766248105,
        0.0000717735019862,
        0.0000697302530170,
        0.0000677451680531,
        0.0000658165881759,
        0.0000639429199509,
        0.0000621225844952,
        0.0000603540793236,
        0.0000586359165027,
        0.0000569666626689,
        0.0000553449353902,
        0.0000537693740625,
        0.0000522386617376,
        0.0000507515323989,
        0.0000493067309435,
        0.0000479030677525,
        0.0000465393568447,
        0.0000452144740848,
        0.0000439273062511,
        0.0000426767801400,
        0.0000414618552895,
        0.0000402815167035,
        0.0000391347784898,
        0.0000380206874979,
        0.0000369383124053,
        0.0000358867509931,
        0.0000348651265085,
        0.0000338725840265,
        0.0000329082940880,
        0.0000319714599755,
        0.0000310612922476,
};

static const float _it_resonance_table[128]={
	1.000000,
	0.978645,
	0.957745,
	0.937292,
	0.917276,
	0.897687,
	0.878517,
	0.859756,
	0.841395,
	0.823427,
	0.805842,
	0.788633,
	0.771792,
	0.755310,
	0.739180,
	0.723394,
	0.707946,
	0.692827,
	0.678032,
	0.663552,
	0.649382,
	0.635514,
	0.621942,
	0.608660,
	0.595662,
	0.582942,
	0.570493,
	0.558309,
	0.546387,
	0.534718,
	0.523299,
	0.512124,
	0.501187,
	0.490484,
	0.480010,
	0.469759,
	0.459727,
	0.449909,
	0.440301,
	0.430899,
	0.421697,
	0.412691,
	0.403878,
	0.395253,
	0.386812,
	0.378552,
	0.370467,
	0.362556,
	0.354813,
	0.347236,
	0.339821,
	0.332564,
	0.325462,
	0.318511,
	0.311709,
	0.305053,
	0.298538,
	0.292163,
	0.285924,
	0.279818,
	0.273842,
	0.267994,
	0.262271,
	0.256670,
	0.251189,
	0.245824,
	0.240575,
	0.235437,
	0.230409,
	0.225489,
	0.220673,
	0.215961,
	0.211349,
	0.206835,
	0.202418,
	0.198096,
	0.193865,
	0.189725,
	0.185674,
	0.181708,
	0.177828,
	0.174030,
	0.170314,
	0.166677,
	0.163117,
	0.159634,
	0.156225,
	0.152889,
	0.149624,
	0.146428,
	0.143301,
	0.140241,
	0.137246,
	0.134315,
	0.131447,
	0.128640,
	0.125893,
	0.123204,
	0.120573,
	0.117998,
	0.115478,
	0.113012,
	0.110599,
	0.108237,
	0.105925,
	0.103663,
	0.101450,
	0.099283,
	0.097163,
	0.095088,
	0.093057,
	0.091070,
	0.089125,
	0.087222,
	0.085359,
	0.083536,
	0.081752,
	0.080006,
	0.078298,
	0.076626,
	0.074989,
	0.073388,
	0.071821,
	0.070287,
	0.068786,
	0.067317,
	0.065879,
	0.064473
};


void Mixer_Soft::set_voice_filter(int p_voice_index,bool p_enabled,Uint8 p_cutoff, Uint8 p_resonance ) {

	if (p_voice_index<0 || p_voice_index>=MAX_VIRTUAL_VOICES) {
		ERR_PRINT("Invalid voice index!");
		return ;
	}
	
	voice_array[p_voice_index].fx.filter.enabled=p_enabled;
	voice_array[p_voice_index].fx.filter.cutoff=p_cutoff;
	voice_array[p_voice_index].fx.filter.resonance=p_resonance;

	if (!p_enabled) {	
		voice_array[p_voice_index].fx.filter.old_c1=0;
		voice_array[p_voice_index].fx.filter.old_c2=0;
		voice_array[p_voice_index].fx.filter.old_c3=0;
	}
}

void Mixer_Soft::process_filter(int p_voice ) {
	
	Voice::FX::FilterKernel &filter=voice_array[p_voice].fx.filter;
			
	if (filter.cutoff==filter.cutoff_cache && filter.resonance==filter.resonance_cache && data.mixfreq_current==filter.mixfreq_cache)
		return; //nothing to do..
	
	
#if 0


	float inv_angle = (float)((float)filter.cutoff * ((2*3.14159265358979323846)))/data.mixfreq_current;
	inv_angle=1.0/inv_angle;
		
	float loss = losstable[filter.resonance>>1];
	float d, e;

	d = (1.0f - loss) / inv_angle;
	if (d > 2.0f) d = 2.0f;
	d = (loss - d) * inv_angle;
	e = inv_angle * inv_angle;
	float a = 1.0f / (1.0f + d + e);
	float c = -e * a;
	float b = 1.0f - a - c;
	
	filter.c1=(Sint32)(a*FILTER_LENGTH);
	filter.c2=(Sint32)(b*FILTER_LENGTH);
	filter.c3=(Sint32)(c*FILTER_LENGTH);

#else



/*
	float rc = _it_cutoff_table[filter.cutoff>>1] * data.mixfreq_current;
	
	float reso = _it_resonance_table[filter.resonance>>1];
	float rrc = reso * rc;
	float rc2 = rc*rc;
	
	float a = 1.0 / (2.0 - reso + rrc + rc2 );
	float b = a * (1.0 - reso + rrc + rc2*2);
	float c = 1.0 - a - b;

	filter.c1=(Sint32)(a*FILTER_LENGTH);
	filter.c2=(Sint32)(b*FILTER_LENGTH);
	filter.c3=(Sint32)(c*FILTER_LENGTH);
*/
	// this filter sucks ass so much that jeff had no choice but to do it in either 64 bits 
	float g =  data.mixfreq_current;
	g *=_it_cutoff_table[filter.cutoff>>1];
	float h = g;
	g = h*g;
	float i = _it_resonance_table[filter.resonance>>1];
	h *= i;
	float j = 1;
	i -= j;
	h += i;
	i = 1;
	i += h;
	i += g;
	j = 1;
	i = j/i;
	float a = i;
	h += g;
	g += h;
	g *= i;
	float b = g;

	float c = 1.0 - a - b;


	filter.c1=(Sint32)(a*FILTER_LENGTH);
	filter.c2=(Sint32)(b*FILTER_LENGTH);
	filter.c3=(Sint32)(c*FILTER_LENGTH);


#endif
		
	filter.cutoff_cache=filter.cutoff;
	filter.resonance_cache=filter.resonance;
	filter.mixfreq_cache=data.mixfreq_current;
}